package ai

import (
	"context"
	"fmt"
	"sync"
	"time"

	"yanxue_ai_go/pkg/common/ai/types"
	"yanxue_ai_go/pkg/common/logger"

	"go.uber.org/zap"
)

// DefaultModelManager 默认模型管理器实现
type DefaultModelManager struct {
	models          map[string]types.AIModel
	providerModels  map[types.ModelProvider][]string
	typeModels      map[types.ModelType][]string
	modelConfigs    map[string]map[string]interface{}
	healthStatus    map[string]error
	lastHealthCheck time.Time
	mu              sync.RWMutex
}

/*
*

  - NewModelManager 创建并初始化一个新的AI模型管理器实例
    *

  - <p>该函数返回一个实现了types.ModelManager接口的DefaultModelManager实例，

  - 用于统一管理多个AI模型的注册、查询、配置和健康状态。</p>
    *

  - <p><b>设计说明：</b></p>

  - <ul>

  - <li>采用分层索引结构，支持按提供商、类型快速查找模型</li>

  - <li>线程安全设计，支持并发访问</li>

  - <li>支持动态模型注册和配置管理</li>

  - </ul>
    *

  - @return types.ModelManager 新创建的模型管理器实例

  - <ul>

  - <li>models - 存储所有已注册的AI模型实例，key为模型ID</li>

  - <li>providerModels - 按模型提供商分类的索引，便于按提供商快速查找</li>

  - <li>typeModels - 按模型类型分类的索引，便于按类型快速查找</li>

  - <li>modelConfigs - 各模型的配置参数映射，支持模型个性化设置</li>

  - <li>healthStatus - 记录各模型的健康状态，用于故障检测和负载均衡</li>

  - </ul>
    *

  - @since 1.0

  - @see types.ModelManager

  - @see DefaultModelManager
    *

  - @example

  - <pre>

  - manager := NewModelManager()

  - // 注册模型

  - manager.RegisterModel(openaiModel)

  - // 按条件查找模型

  - models, _ := manager.GetModelsByProvider("openai")

  - </pre>
*/
func NewModelManager() types.ModelManager {
	return &DefaultModelManager{
		// 核心存储：模型ID -> 模型实例映射，支持快速查找
		models: make(map[string]types.AIModel),

		// 提供商索引：按AI服务提供商分类的模型ID列表
		// 例如：openai -> [gpt-3.5-turbo, gpt-4], anthropic -> [claude-3]
		providerModels: make(map[types.ModelProvider][]string),

		// 类型索引：按模型功能类型分类的模型ID列表
		// 例如：text-generation -> [gpt-3.5, claude], image-generation -> [dall-e]
		typeModels: make(map[types.ModelType][]string),

		// 配置存储：模型ID -> 配置参数映射
		// 支持温度、最大token数、价格等个性化配置
		modelConfigs: make(map[string]map[string]interface{}),

		// 健康监控：模型ID -> 健康状态映射
		// 用于记录连接错误、API限制等异常状态
		healthStatus: make(map[string]error),
	}
}

// RegisterModel 注册模型
func (m *DefaultModelManager) RegisterModel(model types.AIModel) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	info := model.GetModelInfo()
	modelID := info.ID

	// 检查模型是否已存在
	if _, exists := m.models[modelID]; exists {
		return fmt.Errorf("model %s already registered", modelID)
	}

	// 注册模型
	m.models[modelID] = model

	// 更新提供商索引
	provider := model.GetProvider()
	m.providerModels[provider] = append(m.providerModels[provider], modelID)

	// 更新类型索引
	modelType := model.GetType()
	m.typeModels[modelType] = append(m.typeModels[modelType], modelID)

	// 初始化配置
	m.modelConfigs[modelID] = model.GetConfig()

	logger.Logger.Info("Model registered successfully",
		zap.String("model_id", modelID),
		zap.String("provider", string(provider)),
		zap.String("type", string(modelType)))

	return nil
}

// UnregisterModel 注销模型
func (m *DefaultModelManager) UnregisterModel(modelID string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	model, exists := m.models[modelID]
	if !exists {
		return fmt.Errorf("model %s not found", modelID)
	}

	// 删除模型
	delete(m.models, modelID)
	delete(m.modelConfigs, modelID)
	delete(m.healthStatus, modelID)

	// 更新索引
	provider := model.GetProvider()
	m.removeFromSlice(m.providerModels[provider], modelID)

	modelType := model.GetType()
	m.removeFromSlice(m.typeModels[modelType], modelID)

	logger.Logger.Info("Model unregistered successfully", zap.String("model_id", modelID))
	return nil
}

// GetModel 获取指定模型
func (m *DefaultModelManager) GetModel(modelID string) (types.AIModel, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	model, exists := m.models[modelID]
	if !exists {
		return nil, fmt.Errorf("model %s not found", modelID)
	}

	return model, nil
}

// GetModelsByProvider 根据提供商获取模型
func (m *DefaultModelManager) GetModelsByProvider(provider types.ModelProvider) ([]types.AIModel, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	modelIDs, exists := m.providerModels[provider]
	if !exists {
		return nil, fmt.Errorf("no models found for provider %s", provider)
	}

	var models []types.AIModel
	for _, modelID := range modelIDs {
		if model, exists := m.models[modelID]; exists {
			models = append(models, model)
		}
	}

	return models, nil
}

// GetModelsByType 根据类型获取模型
func (m *DefaultModelManager) GetModelsByType(modelType types.ModelType) ([]types.AIModel, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	modelIDs, exists := m.typeModels[modelType]
	if !exists {
		return nil, fmt.Errorf("no models found for type %s", modelType)
	}

	var models []types.AIModel
	for _, modelID := range modelIDs {
		if model, exists := m.models[modelID]; exists {
			models = append(models, model)
		}
	}

	return models, nil
}

// ListModels 列出所有模型信息
func (m *DefaultModelManager) ListModels() ([]types.ModelInfo, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	var modelInfos []types.ModelInfo
	for _, model := range m.models {
		modelInfos = append(modelInfos, model.GetModelInfo())
	}

	return modelInfos, nil
}

// GetBestModel 根据标准选择最佳模型
func (m *DefaultModelManager) GetBestModel(criteria types.ModelSelectionCriteria) (types.AIModel, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	var candidates []types.AIModel

	// 根据标准筛选候选模型
	for _, model := range m.models {
		info := model.GetModelInfo()

		// 检查提供商
		if criteria.Provider != nil && info.Provider != *criteria.Provider {
			continue
		}

		// 检查类型
		if criteria.Type != nil && info.Type != *criteria.Type {
			continue
		}

		// 检查最大tokens
		if criteria.MaxTokens != nil && info.MaxTokens < *criteria.MaxTokens {
			continue
		}

		// 检查成本
		if criteria.MaxCost != nil && info.OutputPrice > *criteria.MaxCost {
			continue
		}

		// 检查功能
		if len(criteria.Features) > 0 {
			hasAllFeatures := true
			for _, required := range criteria.Features {
				found := false
				for _, feature := range info.Features {
					if feature == required {
						found = true
						break
					}
				}
				if !found {
					hasAllFeatures = false
					break
				}
			}
			if !hasAllFeatures {
				continue
			}
		}

		candidates = append(candidates, model)
	}

	if len(candidates) == 0 {
		return nil, fmt.Errorf("no models match the selection criteria")
	}

	// 根据性能要求选择
	if criteria.Performance != nil {
		switch *criteria.Performance {
		case "fast":
			// 选择延迟最低的模型 (简化实现：选择第一个)
			return candidates[0], nil
		case "quality":
			// 选择质量最高的模型 (简化实现：选择价格最高的)
			bestModel := candidates[0]
			bestPrice := bestModel.GetModelInfo().OutputPrice
			for _, candidate := range candidates[1:] {
				if candidate.GetModelInfo().OutputPrice > bestPrice {
					bestModel = candidate
					bestPrice = candidate.GetModelInfo().OutputPrice
				}
			}
			return bestModel, nil
		case "balanced":
			// 选择平衡的模型 (简化实现：选择中等价位)
			return candidates[len(candidates)/2], nil
		}
	}

	// 默认返回第一个候选模型
	return candidates[0], nil
}

// HealthCheck 健康检查
func (m *DefaultModelManager) HealthCheck(ctx context.Context) (map[string]error, error) {
	m.mu.Lock()
	defer m.mu.Unlock()

	// 避免频繁健康检查
	if time.Since(m.lastHealthCheck) < 30*time.Second {
		return m.healthStatus, nil
	}

	m.healthStatus = make(map[string]error)

	for modelID, model := range m.models {
		err := model.Health(ctx)
		m.healthStatus[modelID] = err

		if err != nil {
			logger.Logger.Error("Model health check failed",
				zap.String("model_id", modelID),
				zap.Error(err))
		}
	}

	m.lastHealthCheck = time.Now()
	return m.healthStatus, nil
}

// removeFromSlice 从切片中移除指定元素
func (m *DefaultModelManager) removeFromSlice(slice []string, item string) []string {
	for i, v := range slice {
		if v == item {
			return append(slice[:i], slice[i+1:]...)
		}
	}
	return slice
}

// GlobalModelManager 全局模型管理器实例
var GlobalModelManager types.ModelManager

// InitializeModelManager 初始化全局模型管理器
func InitializeModelManager() {
	GlobalModelManager = NewModelManager()
	logger.Logger.Info("Global model manager initialized")
}
